import { ObjectId } from "mongodb";
import { MongodbClient } from "../lib/db.client.mongodb";
import { PgClient } from "../lib/db.client.pg";

import { ENUM_TON_ORDER, TonOrder, TonSku, User } from "qqlx-core";
import { getConditionMatchEnum, toDivideSafe, TonSkuSchema, getConditionMatchStr, getTplIvId } from "qqlx-cdk";

import { User as OldUser } from "../../../qqlx.old/qqlx-core";
import { Corp as OldCorp } from "../../../qqlx.old/qqlx-core";
import { Order as OldOrder, ENUM_ORDER } from "../../../qqlx.old/qqlx-core";
import { Sku } from "../../../qqlx.old/qqlx-core";

import { TonSkuDao } from "../dao/river";
import { ENUM_POUNDS_FORMULA } from "../../../qqlx.old/qqlx-core";
import { doBashPrint } from "../lib/log";

export async function doTonSkuSaleInsert(
  mongo_master_corp_id: OldCorp["_id"],
  _id_to_user_map: Map<OldUser["_id"], User>,
  _id_to_sale_order_map: Map<OldUser["_id"], TonOrder>,
) {
  const mongodbClient = new MongodbClient("mongodb://localhost:27017/qqlx");
  const pgClient = new PgClient("127.0.0.1", "5432", "production", "postgres", "postgres");

  console.group("\n开始迁移mongo商品销售数据");
  const stat = { before: 0, wanner: 0, now: 0 };
  const pg_sale_order_uuiid32_to_skus_map = new Map<TonOrder["uuid32"], TonSku[]>();

  try {
    await mongodbClient.start();

    const colCorps = mongodbClient.getCollection("corps");
    const corp = (await colCorps.findOne<OldCorp>({ _id: mongo_master_corp_id as unknown as ObjectId })) as OldCorp;
    const corpQuery = { corpId: corp._id as unknown as ObjectId };

    // 根据公司，查询销售相关订单
    const orderQuery = { ...corpQuery, type: ENUM_ORDER.SALES };
    const colOrders = mongodbClient.getCollection("orders");
    const mongo_sale_orders = await colOrders.find<OldOrder>(orderQuery).toArray();
    console.log("旧数据（销售订单）", mongo_sale_orders.length);

    // 根据公司，查询销售相关商品
    const colSkus = mongodbClient.getCollection("skus");
    const oldSaleSkus = await colSkus.find<Sku>(orderQuery).toArray();
    console.log("旧数据（销售商品）", oldSaleSkus.length);
    stat.wanner = oldSaleSkus.length;

    // 通过订单ID，将商品分组
    const oldOrderSkuMap = new Map<OldOrder["_id"], Sku[]>();
    for (const oldSku of oldSaleSkus) {
      if (!oldOrderSkuMap.has(oldSku.orderId)) {
        oldOrderSkuMap.set(oldSku.orderId, []);
      }
      oldOrderSkuMap.get(oldSku.orderId)!.push(oldSku);
    }

    // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░░░░▄▄▄▄▄▄░░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░░▄█▀▀▀▀▀█▄░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░▄█░░▄▄▄░░█▄░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░█░░█▀▀█░░█░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░█░░█▀▀█░░█░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░█░░█▄▄█░░█░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░▀▄▀▄▄▄▄▄▀▄▀░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

    const pgClientIns = await pgClient.start();
    const skuDao = new TonSkuDao(pgClientIns.getRepository<TonSku>(TonSkuSchema));

    const master = _id_to_user_map.get(corp.userId) as User;
    const pg_sale_order_condis = [getConditionMatchStr("refOwnerUUid32", master.uuid32), getConditionMatchEnum("type", ENUM_TON_ORDER.SALE)];

    const pgCount = await skuDao.count(pg_sale_order_condis);
    if (pgCount === 0) {
      const errorCount = { value: 0 };

      //
      const schemaLs: TonSku[] = [];
      mongo_sale_orders.map((mongo_sale_order) => {
        for (const oldSku of oldOrderSkuMap.get(mongo_sale_order._id) || []) {
          const { schema, isError } = getDefaultSku(oldSku);
          if (isError) errorCount.value++;

          const pg_order = _id_to_sale_order_map.get(mongo_sale_order._id) as TonOrder;
          schema.refOwnerUUid32 = pg_order.refOwnerUUid32;

          schema.refTonOrderGroupId = pg_order.refTonOrderGroupId;
          schema.refTonOrderId = pg_order.uuid32;
          schema.isOrderDisabled = pg_order.isDisabled;

          schema.formulaName = oldSku.formula === ENUM_POUNDS_FORMULA.TS_PLATE ? "冷轧板过磅" : ""; // 税额如果大于0，表示需要公式
          schema.formulaContent = oldSku.formula === ENUM_POUNDS_FORMULA.TS_PLATE ? "7.85*(A/10)*(B/10)*(C/10)/1000/1000" : "";

          // 交易7要素
          schema.tradeId = "";
          schema.tradeTime = pg_order.tradeTime;
          schema.tradeYear = pg_order.tradeYear;
          schema.tradeMonth = pg_order.tradeMonth;
          schema.tradeScope = pg_order.tradeScope;
          schema.refCreatorId = pg_order.refCreatorId;
          schema.refContactId = pg_order.refContactId;
          schemaLs.push(schema);

          // 数据缓存
          if (!pg_sale_order_uuiid32_to_skus_map.has(pg_order.uuid32)) {
            pg_sale_order_uuiid32_to_skus_map.set(pg_order.uuid32, []);
          }
          pg_sale_order_uuiid32_to_skus_map.get(pg_order.uuid32)!.push(schema);
        }
      });
      console.log("异常商品个数", errorCount);

      // 1.迁移销售/发货商品
      const batchCount = 2000;
      const createds: TonSku[] = [];
      while (schemaLs.length > 0) {
        const part = schemaLs.splice(0, batchCount);
        const ls = await skuDao.insertManyAndQuery(part);
        createds.push(...ls);
        doBashPrint(`正在推送商品（${batchCount}）剩余${schemaLs.length}`);
      }
    }

    // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░░░░▄▄▄▄▄▄░░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░░▄█▀▀▀▀▀█▄░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░▄█░░▄▄▄░░█▄░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░█░░█▀▀█░░█░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░█░░█▀▀█░░█░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░█░░█▄▄█░░█░░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░▀▄▀▄▄▄▄▄▀▄▀░░░░░░░░░░░░░░░░░░░░░░░░░░
    // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

    const pgCountFinal = await skuDao.count(pg_sale_order_condis);
    stat.now = pgCountFinal;

    console.log(`🔴迁移前 >> 迁移后 / river_ton_sku_sale`, stat.before, stat.now);
    console.log(`期望`, stat.wanner);
    console.log(`📉误差`, stat.now - stat.before - stat.wanner);
    console.groupEnd();
    console.log("====================================");
  } finally {
    await pgClient.stop();
    await mongodbClient.stop();
  }

  return { pg_sale_order_uuiid32_to_skus_map };
}

function getDefaultSku(mongo_sku: Sku) {
  const schema: TonSku = new TonSkuSchema();
  schema.timeCreate = mongo_sku.timeCreate.toString();
  schema.timeUpdate = mongo_sku.timeUpdate.toString();
  schema.type = ENUM_TON_ORDER.SALE;

  schema.count = mongo_sku.count;
  schema.ton = mongo_sku.isPriceInPounds ? toDivideSafe(mongo_sku.pounds, 1000, 3) : 0;
  schema.isTonAble = mongo_sku.isPriceInPounds;
  schema.price = Math.min(toDivideSafe(mongo_sku.price, 100, 2), 2147483);

  schema.name = mongo_sku.name || "-";
  schema.norm = mongo_sku.norm || "-";
  schema.unit = mongo_sku.unit || "-";
  schema.remark = mongo_sku.remark;
  schema.ivid = getTplIvId(schema, "");

  const isError = [schema.name, schema.norm, schema.unit].includes("-");
  return { schema, isError };
}
